(function (_super) {
    var io = ppt.io;

    var roles = {};
    var monsters = {};
    var propList = {};
    var bubbleList = {};

    var ACTIONS = {
        "game::begin" : function (data) {
            if(data.time == 0){
                for(var i in this.roles){
                    this.roles[i].start();
                }
            }
        },
        "game::result" : function (data) {
            switch(data.mode){
                case "pvp":
                    var winCamp = data.winCamp;

                    if(winCamp == "draw"){return;}
                    for(var i in this.roles){
                        (this.roles[i].camp == winCamp) && this.roles[i].act("happy");
                    }
                    break;
                case "pve":
                    if(data.res == "win"){
                        for(var i in this.roles){
                            this.roles[i].act("happy");
                        }
                    }
                    break;
            }
            
        },
        "bubble::set" : function (data) {
            var bubble = Game.Bubble.create(data);

            this.bubbleList[data.bubbleId] = bubble;
            this.tiled.add(bubble);
        },
        "bubble::boom" : function (data) {
            if(this.bubbleList[data.bubbleId]){
                this.bubbleList[data.bubbleId].boom(data.boomRange);
                delete this.bubbleList[data.bubbleId];
            }
        },
        "bubble::move" : function (data) {
            if(this.bubbleList[data.bubbleId]){
                this.bubbleList[data.bubbleId].pos(data.point.x * GAME_MOVE_RATE, data.point.y * GAME_MOVE_RATE);
            }
        },

        "map::remove" : function (data) {
            for(var i in data){
                var x = (data[i].x - 4) / 8;
                var y = (data[i].y - 4) / 8;
                this.tiled.remove(x, y);
            }
        },
        "map::moveBox" : function (data) {
            var x = (data.point.x - 4) / 8;
            var y = (data.point.y - 4) / 8;

            this.tiled.move({x : x, y : y}, data.direction);
        },

        "move::move" : function (data) {
            this.roles[data.userId].move(data);
        },
        "move::jump" : function (data) {
            this.roles[data.userId].jump(data.point, data.direction);
        },
        "role::trap" : function (data) {
            for(var i in data){
                this.roles[data[i]].act("trap");
            }
        },
        "role::die" : function (data) {
            for(var i in data){
                this.roles[data[i]].act("die");
            }
        },
        "role::reborn" : function (data) {
            this.roles[data.userId].reBorn(data.point);
        },
        "role::release" : function (data) {
            for(var i in data){
                this.roles[data[i]].act("release");
            }
        },
        "role::cross" : function (data) {
            var target = this.roles[data.userId];
            var me = this.roles[userId];

            if(target.camp == me.camp){
                target.cross(data.type, true);
            }else{
                target.cross(data.type, false);
            }
        },

        "prop::set" : function (data) {
            for(var i in data){
                var prop = Game.Prop.create(data[i]);
                this.propList[data[i].propId] = prop;
                this.tiled.add(prop);
            }
        },
        "prop::destroy" : function (data) {
            for(var i in data){
                var propId = data[i];
                if(this.propList[propId]){
                    this.propList[propId].recover();
                    delete this.propList[propId];
                }
            }
        },

        "skill::start" : function (data) {
            var skillId = data.skillId + "";
            var targets = data.target;

            if(skillId == "2005"){
                var target = this.roles[targets[0]];
                var me = this.roles[userId];

                if(target.camp == me.camp){
                    target.changeState("hit", skillId, 0.5);
                }else{
                    target.changeState("hit", skillId, 0);
                }
            }else{
                for(var i in targets){
                    this.roles[targets[i]].changeState("hit", skillId);
                }
            }
        },
        "skill::end" : function (data) {
            var skillId = data.skillId + "";
            var targets = data.target;

            for(var i in targets){
                this.roles[targets[i]].changeState("release", skillId);
            }
        },

        "ride::mount" : function (data) {
            this.roles[data.userId].ride("mount", data.itemId);
        },
        "ride::dismount" : function (data) {
            this.roles[data.userId].ride("dismount");
        },

        "turret::attack" : function (data) {
            var x = (data.point.x - 4) / 8;
            var y = (data.point.y - 4) / 8;

            this.tiled.attack(x, y);
        },

        "monster::hit" : function (data) {
            this.monsters[data.bossId].act("hit");
        },
        "monster::attack" : function (data) {
            this.monsters[data.bossId].act("attack");
        },
        "monster::move" : function (data) {
            this.monsters[data.bossId].move(data);
        },
        "monster::trap" : function (data) {
            this.monsters[data.bossId].act("trap");
        },
        "monster::die" : function (data) {
            for(var i in data){
                this.monsters[data[i]].act("die", function () {
                    delete this.monsters[data[i]];
                }.bind(this));
            }
        },
        "monster::create" : function (data) {
            this.monsterCreate(data);
        }
    };

    function Fighting(data) {
        Fighting.super(this);

        this.data = null;
        this.BG = null;
        this.tiled = null;

        this.roles = {};
        this.monsters = {};
        this.propList = {};
        this.bubbleList = {};
        this.battleId = null;

        this.init(data);
    }
    Laya.class(Fighting, "Game.Main", _super);
    var _proto = Fighting.prototype;
    _proto.destroy = function () {
        _super.prototype.destroy.call(this, true);

        this.data = null;
        this.BG = null;
        this.tiled = null;
        this.roles = null;
        this.monsters = null;
        this.propList = null;
        this.bubbleList = null;
        this.battleId = null;

        io.unregister(ACTIONS);
    }

    _proto.init = function (data) {
        io.register(ACTIONS, this);
        this.size(GAME_CONFIG.WIDTH, Laya.stage.height);

        this.data = data;
        var rolesData = data.roles;
        var mapPath = data.map.path;
        
        this.battleId = data.battleId;

        var bg = new Laya.Image(mapPath + "/bg.png");
            bg.centerX = 0;
            bg.centerY = 0;

        var tiled = new Game.TiledMap();
            tiled.centerX = 0;
            tiled.centerY = 0;
            tiled.create(mapPath);
        
        for(var i in rolesData){
            var roleData = rolesData[i];
                roleData.point = roleData.point ? roleData.point : {x : 4, y : 4};

            var role = new Game.Role(roleData);
                role.born(roleData.point);

            this.roles[roleData.userId] = role;
            tiled.add(role);
        }

        this.BG = bg;
        this.tiled = tiled;
        this.addChildren(bg, tiled);

        ppt.io.emit({cmd:'game::ready', params:{roomId : this.battleId, type : data.mode}});
    }
    _proto.monsterCreate = function (data) {
        console.log("Monster Create", data);
        var monster = new Game.Monster(data);

        this.monsters[data.bossId] = monster;
        this.tiled.add(monster);
    }

    _proto.enter = function () {
        this.tiled.enter(function () {
            var bossData = this.data.boss;

            if(bossData){
                this.monsterCreate(bossData)
            }
        }.bind(this));
    }

    _proto.resize = function (height) {
        this.height = height;

        this.BG.centerY = 0;
        this.tiled.centerY = 0;
    }
})(Laya.Sprite);